package com.example.userservice.service.impl;

import com.example.userservice.mapper.UserContactApplyMapper;
import com.example.userservice.mapper.UserContactMapper;
import com.example.userservice.mapper.UserInfoMapper;
import com.example.userservice.rabbitmq.publisher.UserPublisher;
import com.example.userservice.service.UserContactApplyService;
import org.example.config.redis.RedisComponent;

import org.example.entity.constants.ConstansMsgType;
import org.example.entity.dto.MessageDto;
import org.example.entity.dto.MessageSendDto;
import org.example.entity.dto.SysSettingDto;
import org.example.entity.enums.*;
import org.example.entity.po.*;
import org.example.entity.query.*;
import org.example.entity.vo.PaginationResultVO;
import org.example.exception.BusinessException;
import org.example.openFeign.GroupClient;
import org.example.utils.CopyTools;
import org.example.utils.StringTools;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * 联系人申请 业务接口实现
 */
@Service("userContactApplyService")
public class UserContactApplyServiceImpl implements UserContactApplyService {

    @Resource
    private UserContactApplyMapper<UserContactApply, UserContactApplyQuery> userContactApplyMapper;

    @Resource
    private UserContactMapper<UserContact, UserContactQuery> userContactMapper;


    @Resource
    private UserInfoMapper<UserInfo, UserInfoQuery> userInfoMapper;


    @Resource
    private RedisComponent redisComponent;
    @Resource
    private UserPublisher userPublisher;

    @Resource
    private GroupClient groupClient;
    /**
     * 根据条件查询列表
     */
    @Override
    public List<UserContactApply> findListByParam(UserContactApplyQuery param) {
        return this.userContactApplyMapper.selectList(param);
    }

    /**
     * 根据条件查询列表
     */
    @Override
    public Integer findCountByParam(UserContactApplyQuery param) {
        return this.userContactApplyMapper.selectCount(param);
    }

    /**
     * 分页查询方法
     */
    @Override
    public PaginationResultVO<UserContactApply> findListByPage(UserContactApplyQuery param) {
        int count = this.findCountByParam(param);
        int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

        SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
        param.setSimplePage(page);
        List<UserContactApply> list = this.findListByParam(param);
        PaginationResultVO<UserContactApply> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
        return result;
    }

    /**
     * 新增
     */
    @Override
    public Integer add(UserContactApply bean) {
        return this.userContactApplyMapper.insert(bean);
    }

    /**
     * 批量新增
     */
    @Override
    public Integer addBatch(List<UserContactApply> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.userContactApplyMapper.insertBatch(listBean);
    }

    /**
     * 批量新增或者修改
     */
    @Override
    public Integer addOrUpdateBatch(List<UserContactApply> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.userContactApplyMapper.insertOrUpdateBatch(listBean);
    }

    /**
     * 多条件更新
     */
    @Override
    public Integer updateByParam(UserContactApply bean, UserContactApplyQuery param) {
        StringTools.checkParam(param);
        return this.userContactApplyMapper.updateByParam(bean, param);
    }

    /**
     * 多条件删除
     */
    @Override
    public Integer deleteByParam(UserContactApplyQuery param) {
        StringTools.checkParam(param);
        return this.userContactApplyMapper.deleteByParam(param);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dealWithApply(HttpServletRequest request,String userId, Integer applyId, Integer status) {
        UserContactApplyStatusEnum statusEnum = UserContactApplyStatusEnum.getByStatus(status);
        if (statusEnum == null || UserContactApplyStatusEnum.INIT == statusEnum){
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }

        UserContactApply apply = userContactApplyMapper.selectByApplyId(applyId);
        if (apply == null || !apply.getReceiveUserId().equals(userId)){
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        //更新申请表中的状态
        UserContactApply updateInfo = new UserContactApply();
        updateInfo.setStatus(statusEnum.getStatus());
        updateInfo.setLastApplyTime(System.currentTimeMillis());

        UserContactApplyQuery query = new UserContactApplyQuery();
        query.setStatus(UserContactApplyStatusEnum.INIT.getStatus());
        query.setApplyId(applyId);

        Integer i = userContactApplyMapper.updateByParam(updateInfo, query);
        if (i == 0){
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }

        if (UserContactApplyStatusEnum.PASS.equals(statusEnum)) {
            addContact(request,apply.getApplyUserId(),userId, apply.getContactId(), apply.getContactType(), UserContactStatusEnum.FRIEND.getStatus());
            return;
        }
        if (UserContactApplyStatusEnum.BLACKLIST.equals(statusEnum)){
            addContact(request,apply.getApplyUserId(),userId,apply.getContactId(),apply.getContactType(),UserContactStatusEnum.BLACKLIST_BE.getStatus());
        }
    }

    //TODO 异步通知chatservice
    @Override
    public void addContact(HttpServletRequest request,String applyId,String recevieId, String contactId, Integer contactType, Integer status) {
        Date curDate = new Date();
        if (contactType.equals(UserContactTypeEnum.GROUP.getType())){
            UserContactQuery query = new UserContactQuery();
            query.setContactId(contactId);
            query.setStatus(UserContactStatusEnum.FRIEND.getStatus());

            Integer i = userContactMapper.selectCount(query);

            SysSettingDto sysSetting = redisComponent.getSysSetting();
            if (i >= sysSetting.getMaxGroupCount()){
                throw new BusinessException("成员已满，无法加入");
            }
        }
        List<UserContact> contactList = new ArrayList<>();
        //申请人添加群或者人
        UserContact userContact = new UserContact();
        userContact.setCreateTime(curDate);
        userContact.setLastUpdateTime(curDate);
        userContact.setContactType(contactType);
        userContact.setStatus(status);
        userContact.setUserId(applyId);
        userContact.setContactId(contactId);
        contactList.add(userContact);
        //申请好友 对方也需要加申请人
        if (contactType.equals(UserContactTypeEnum.USER.getType())){
            userContact = new UserContact();
            userContact.setCreateTime(curDate);
            userContact.setLastUpdateTime(curDate);
            userContact.setContactType(contactType);
            userContact.setStatus(status);
            userContact.setUserId(recevieId);
            userContact.setContactId(applyId);
            contactList.add(userContact);
        }
        //批量插入
        userContactMapper.insertOrUpdateBatch(contactList);

        if (!status.equals(UserContactStatusEnum.FRIEND.getStatus()) && !contactType.equals(UserContactTypeEnum.USER.getType())){
            return;
        }
        if(UserContactTypeEnum.USER.getType().equals(contactType)){
            redisComponent.addUserContact(recevieId,applyId);
        }
        redisComponent.addUserContact(applyId,contactId);
        //创建会话信息
        String sessionId = null;
        if (UserContactTypeEnum.USER.getType().equals(contactType)) {
            sessionId = StringTools.getChatSessionId4User(new String[]{applyId, contactId});
        } else {
            sessionId = StringTools.getChatSessionId4Group(contactId);
        }

        //会话参与人
        //查询申请人信息
        UserInfo applyUserInfo = this.userInfoMapper.selectByUserId(applyId);
        List<ChatSessionUser> chatSessionUserList = new ArrayList<>();
        UserContactApply apply = userContactApplyMapper.selectByApplyUserIdAndReceiveUserIdAndContactId(applyId,recevieId,contactId);
        String applyInfo = apply.getApplyInfo();
        if (UserContactTypeEnum.USER.getType().equals(contactType)) {
            //创建会话
            ChatSession chatSession = new ChatSession();
            chatSession.setSessionId(sessionId);
            chatSession.setLastReceiveTime(curDate.getTime());
            chatSession.setLastMessage(applyInfo);
            //TODO 第一个chatsession
            userPublisher.userSendMsg2ChatDB(chatSession);
//            this.chatSessionMapper.insertOrUpdate(chatSession);

            //申请人session
            ChatSessionUser applySessionUser = new ChatSessionUser();
            applySessionUser.setUserId(applyId);
            applySessionUser.setContactId(contactId);
            applySessionUser.setSessionId(sessionId);
            //查询接收人信息
            UserInfo contactUser = this.userInfoMapper.selectByUserId(contactId);
            applySessionUser.setContactName(contactUser.getNickName());
            chatSessionUserList.add(applySessionUser);

            //接受人session
            ChatSessionUser contactSessionUser = new ChatSessionUser();
            contactSessionUser.setUserId(contactId);
            contactSessionUser.setContactId(applyId);
            contactSessionUser.setSessionId(sessionId);

            contactSessionUser.setContactName(applyUserInfo.getNickName());
            chatSessionUserList.add(contactSessionUser);
            //TODO 第2个chatsession
            userPublisher.userSendMsg2ChatDB(chatSessionUserList);
//            this.chatSessionUserMapper.insertOrUpdateBatch(chatSessionUserList);

            //记录消息消息表
            ChatMessage chatMessage = new ChatMessage();
            chatMessage.setSessionId(sessionId);
            chatMessage.setMessageType(MessageTypeEnum.ADD_FRIEND.getType());
            chatMessage.setMessageContent(applyInfo);
            chatMessage.setSendUserId(applyId);
            chatMessage.setSendUserNickName(applyUserInfo.getNickName());
            chatMessage.setSendTime(curDate.getTime());
            chatMessage.setContactId(contactId);
            chatMessage.setContactType(UserContactTypeEnum.USER.getType());
            chatMessage.setStatus(MessageStatusEnum.SENDED.getStatus());
            //TODO 第3个chatsession
            userPublisher.userSendMsg2Chat(chatMessage);
//            chatMessageMapper.insert(chatMessage);

            MessageSendDto messageSendDto = CopyTools.copy(chatMessage, MessageSendDto.class);
            /**
             * 发送给接受好友申请的人
             */
            userPublisher.sendMessage(messageSendDto);
//            messageHandler.sendMessage(messageSendDto);

            /**
             * 发送给申请人 发送人就是接收人，联系人就是申请人
             */
            messageSendDto.setMessageType(MessageTypeEnum.ADD_FRIEND_SELF.getType());
            messageSendDto.setContactId(applyId);
            messageSendDto.setExtendData(contactUser);
            //TODO 第4个chatsession
            userPublisher.sendMessage(messageSendDto);
//            messageHandler.sendMessage(messageSendDto);
        }else {
            /**
             * 创建会话
             */
            ChatSession groupSession = new ChatSession();
            groupSession.setSessionId(sessionId);
            groupSession.setLastMessage(String.format(MessageTypeEnum.ADD_GROUP.getInitMessage(),applyInfo));
            groupSession.setLastReceiveTime(curDate.getTime());
            //TODO 第5个chatsession
            userPublisher.userSendMsg2ChatDB(groupSession);
//            chatSessionMapper.insertOrUpdate(groupSession);
            /**
             * 群组和群员建立会话
             */
            ChatSessionUser groupSessionUser = new ChatSessionUser();
            groupSessionUser.setUserId(applyId);
            groupSessionUser.setContactId(contactId);
            //拿到群组信息
            //TODO 第6个chatsession
            MessageDto sendMsg = new MessageDto();
            sendMsg.setMsgType(ConstansMsgType.GET_GROUP_INFO);
            sendMsg.setMsgId("123123");
            userPublisher.userSendMsg2Group4GetInfo(sendMsg);
            GroupInfo groupInfo = (GroupInfo)groupClient.queryGroupByGroupId(request, contactId).getData();
//            GroupInfo groupInfo = groupInfoMapper.selectByGroupId(contactId);
            groupSessionUser.setContactName(groupInfo.getGroupName());

            groupSessionUser.setSessionId(sessionId);

            //TODO 第6个chatsession
            userPublisher.userSendMsg2ChatDB(groupSessionUser);
//            chatSessionUserMapper.insertOrUpdate(groupSessionUser);
            /**
             * 创建群组聊天欢迎信息
             */
            ChatMessage groupMessage = new ChatMessage();
            groupMessage.setSessionId(sessionId);
            groupMessage.setMessageType(MessageTypeEnum.ADD_GROUP.getType());
            groupMessage.setMessageContent(String.format(MessageTypeEnum.ADD_GROUP.getInitMessage(),applyInfo));
            groupMessage.setSendTime(curDate.getTime());
            groupMessage.setContactId(contactId);
            groupMessage.setContactType(contactType);
            groupMessage.setStatus(MessageStatusEnum.SENDED.getStatus());
            //TODO 第6个chatsession
            userPublisher.userSendMsg2Chat(groupMessage);
//            chatMessageMapper.insert(groupMessage);
            String[] strings = {applyId, contactId};
            userPublisher.userSendMsg2Chat(strings);
//            channelContextUtils.addUser2Group(applyId,contactId);
            //组装发送消息
            MessageSendDto messageSendDto = CopyTools.copy(groupMessage, MessageSendDto.class);

            messageSendDto.setContactId(contactId);

            //获取群人数量
            UserContactQuery query = new UserContactQuery();
            query.setContactId(contactId);
            query.setStatus(UserContactStatusEnum.FRIEND.getStatus());
            Integer i = userContactMapper.selectCount(query);
            messageSendDto.setMemberCount(i);
//            messageSendDto.setContactName(groupInfo.getGroupName());
            userPublisher.sendMessage(messageSendDto);
//            messageHandler.sendMessage(messageSendDto);
        }
    }
}